package cn.yilongquan.controller;

import cn.yilongquan.authorize.PreAuthorize;
import cn.yilongquan.service.RoleService;
import cn.yilongquan.user.domain.Role;
import cn.yilongquan.user.query.RoleQuery;
import cn.yilongquan.util.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@Api(value = "role相关的接口", tags = "角色管理")
@RestController
@RequestMapping("/role")
public class RoleController {

    @Autowired
    private RoleService roleService;

    /**
     * 根据ID查询角色
     */
    @ApiOperation(value = "查询指定角色信息")
    @GetMapping("/{id}")
    @PreAuthorize(sn = "role:findById", name = "根据ID查询角色", descs = "根据ID查询指定角色的详细信息")
    public R findById(@PathVariable("id") Long id) {
        return R.ok(roleService.findById(id));
    }

    /**
     * 查询所有角色
     */
    @ApiOperation(value = "查询所有角色信息")
    @GetMapping
    @PreAuthorize(sn = "role:findAll", name = "查询所有角色", descs = "查询系统中所有的角色信息")
    public R findAll() {
        return R.ok(roleService.findAll());
    }

    /**
     * 根据ID删除角色
     */
    @ApiOperation(value = "删除指定角色信息")
    @DeleteMapping("/{id}")
    @PreAuthorize(sn = "role:deleteById", name = "根据ID删除角色", descs = "根据ID删除指定的角色")
    public R deleteById(@PathVariable("id") Long id) {
        try {
            roleService.deleteById(id);
            return R.ok();
        } catch (Exception e) {
            return R.fail(e.getMessage());
        }
    }

    /**
     * 批量删除角色
     */
    @ApiOperation(value = "批量删除角色信息")
    @PostMapping("/deleteAll")
    @PreAuthorize(sn = "role:batchDelete", name = "批量删除角色", descs = "根据ID列表批量删除角色")
    public R batchDelete(@RequestBody List<Long> ids) {
        try {
            roleService.batchDelete(ids);
            return R.ok();
        } catch (Exception e) {
            return R.fail(e.getMessage());
        }
    }

    /**
     * 添加或修改角色
     */
    @ApiOperation(value = "添加或修改角色信息")
    @PreAuthorize(sn = "role:save", name = "添加或修改角色", descs = "新增角色或更新已有角色信息")
    @PostMapping("/save")
    public R save(@RequestBody Role role) {
        System.out.println("接收到保存角色请求");
        try {
            // 1. 校验角色编码唯一性
            boolean isUnique = roleService.isRoleCodeUnique(role.getSn(), role.getId());
            if (!isUnique) {
                return R.fail("角色编码已存在，请更换");
            }
            // 2. 执行保存/更新逻辑
            if (role.getId() == null) {
                roleService.add(role); // 新增（ID会自动回填）
            } else {
                roleService.update(role); // 更新
            }
            // 3. 处理关联关系
            handlePermissionRelations(role);
            handleMenuRelations(role);
            return R.ok("操作成功");
        } catch (Exception e) {
            // 返回友好提示
            return R.fail("系统异常，角色保存失败，请稍后重试");
        }
    }

    /**
     * 处理角色与权限的关联关系（修复递归调用问题）
     */
    private void handlePermissionRelations(Role role) {
        if (role.getPermissionIds() != null) {
            // 将前端传递的单个ID或列表转换为统一的List<Long>
            List<Long> permissionIds = convertToList(role.getPermissionIds());
            roleService.saveRolePermissions(role.getId(), permissionIds);
        }
    }

    /**
     * 处理角色与菜单的关联关系（修复递归调用问题）
     */
    private void handleMenuRelations(Role role) {
        if (role.getMenuIds() != null) {
            // 将前端传递的单个ID或列表转换为统一的List<Long>
            List<Long> menuIds = convertToList(role.getMenuIds());
            roleService.saveRoleMenus(role.getId(), menuIds);
        }
    }

    /**
     * 将对象转换为Long列表，支持单个值和列表两种输入
     */
    @SuppressWarnings("unchecked")
    private List<Long> convertToList(Object value) {
        List<Long> result = new ArrayList<>();

        if (value instanceof List) {
            // 如果是列表，遍历转换每个元素
            for (Object item : (List<Object>) value) {
                result.add(convertToLong(item));
            }
        } else {
            // 如果是单个值，直接添加到列表
            result.add(convertToLong(value));
        }

        return result;
    }

    /**
     * 将对象转换为Long类型（支持数字、字符串等类型）
     */
    private Long convertToLong(Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof Number) {
            return ((Number) value).longValue();
        }
        if (value instanceof String) {
            return Long.parseLong((String) value);
        }
        throw new IllegalArgumentException("无法将 " + value.getClass() + " 类型转换为Long");
    }

    /**
     * 分页查询角色
     */
    @ApiOperation(value = "分页查询角色信息")
    @PostMapping("/list")
    @PreAuthorize(sn = "role:pageList", name = "分页查询角色", descs = "根据查询条件分页查询角色信息")
    public R pageList(@RequestBody RoleQuery roleQuery) {
        return roleService.pageList(roleQuery);
    }

    /**
     * 查询角色关联的权限ID列表
     */
    @ApiOperation(value = "查询角色关联的权限ID列表")
    @GetMapping("/{roleId}/permissions")
    @PreAuthorize(sn = "role:getRolePermissions", name = "查询角色与权限联系", descs = "查询角色与权限联系")
    public R getRolePermissions(@PathVariable Long roleId) {
        List<Long> permissionIds = roleService.getPermissionIdsByRoleId(roleId);
        return R.ok(permissionIds);
    }

    /**
     * 查询角色关联的菜单ID列表（确保返回列表格式）
     */
    @ApiOperation(value = "查询角色关联的菜单ID列表")
    @GetMapping("/{roleId}/menus")
    @PreAuthorize(sn = "role:menus", name = "查询角色与菜单联系", descs = "查询角色与菜单联系")
    public R getMenuIdsByRoleId(@PathVariable Long roleId) {
        List<Long> menus = roleService.getMenuIdsByRoleId(roleId);
        // 确保返回空列表而非null，避免前端处理问题
        return R.ok(menus != null ? menus : new ArrayList<>());
    }
}